package handlers

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"shopback/models"
	"strconv"

	"github.com/gorilla/mux"
)

// AddProduct 用于添加新商品
    // @Summary 添加新商品
    // @Description 添加一个新的商品到数据库。
    // @Tags 商品
    // @Accept json
    // @Produce json
    // @Param product body models.Product true "商品信息"
    // @Success 201 {string} string "商品添加成功", "product_id":int
    // @Failure 400 {string} string "请求参数错误"
    // @Failure 500 {string} string "服务器内部错误"
    // @Router /products [post]
func AddProduct(w http.ResponseWriter, r *http.Request) {
	var product models.Product
	// 解析请求体中的 JSON 数据到 product 结构体
	if err := json.NewDecoder(r.Body).Decode(&product); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// 调用模型层的 AddProduct 函数来将商品添加到数据库
	productID, err := models.AddProduct(product)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// 成功添加商品后，返回 201 Created 状态和商品 ID
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated) // HTTP 201 Created

	// 返回添加的商品 ID
	json.NewEncoder(w).Encode(map[string]interface{}{
		"message":    "商品添加成功",
		"product_id": productID,
	})
}

// SearchProducts 搜索商品
    // @Summary 搜索商品
    // @Description 根据输入的关键词返回所有包含该关键词名字的商品
    // @Tags 商品
    // @Accept json
    // @Produce json
    // @Param keyword query string true "搜索关键词"
    // @Success 200 {array} models.Product "商品列表"
    // @Failure 400 {string} string "无效的查询参数"
    // @Failure 500 {string} string "服务器内部错误"
    // @Router /products/search [get]
func SearchProducts(w http.ResponseWriter, r *http.Request) {
	keyword := r.URL.Query().Get("keyword")
	if keyword == "" {
		http.Error(w, "搜索关键词不能为空", http.StatusBadRequest)
		return
	}

	// 使用 models 包中的函数进行搜索
	products, err := models.SearchProducts(keyword)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if len(products) == 0 {
		http.Error(w, "未找到匹配的商品", http.StatusNotFound)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(products)
}

// GetAllProducts 获取所有商品
    // @Summary 获取所有商品
    // @Description 返回系统中的所有商品列表
    // @Tags 商品
    // @Accept json
    // @Produce json
    // @Success 200 {array} models.Product "商品列表"
    // @Failure 500 {string} string "服务器内部错误"
    // @Router /products [get]
func GetAllProducts(w http.ResponseWriter, r *http.Request) {
	// 调用模型层函数获取所有商品
	products, err := models.GetAllProducts()
	if err != nil {
		w.Header().Set("Content-Type", "application/json")
		http.Error(w, fmt.Sprintf(`{"message": "获取商品列表失败: %v"}`, err), http.StatusInternalServerError)
		return
	}

	// 如果没有商品，返回空数组而不是错误
	if len(products) == 0 {
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode([]models.Product{})
		return
	}

	// 返回商品列表
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(products)
}

// GetProductByID 获取单个商品
    // @Summary 获取单个商品
    // @Description 根据商品ID获取单个商品的详细信息。
    // @Tags 商品
    // @Accept json
    // @Produce json
    // @Param id path int true "商品ID"
    // @Success 200 {object} models.Product "商品信息"
    // @Failure 400 {string} string "无效的商品ID"
    // @Failure 404 {string} string "商品未找到"
    // @Failure 500 {string} string "服务器内部错误"
    // @Router /products/{id} [get]
func GetProductByID(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id, err := strconv.Atoi(vars["id"])
    if err != nil {
        http.Error(w, "无效的商品ID", http.StatusBadRequest)
        log.Println("Keyword:", id)
        return
    }

    product, err := models.GetProductByID(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    json.NewEncoder(w).Encode(product)
}

// DeleteProduct 用于删除指定 ID 的商品
    // @Summary 删除商品
    // @Description 根据商品ID删除指定的商品。
    // @Tags 商品
    // @Accept json
    // @Produce json
    // @Param id path int true "商品ID"
    // @Success 200 {string} string "商品删除成功"
    // @Failure 400 {string} string "无效的商品ID"
    // @Failure 404 {string} string "商品未找到"
    // @Failure 500 {string} string "服务器内部错误"
    // @Router /products/{id} [delete]
func DeleteProduct(w http.ResponseWriter, r *http.Request) {
	// 从 URL 中提取商品 ID
	vars := mux.Vars(r)
	idStr := vars["id"]

	// 将 id 从字符串转换为整数
	id, err := strconv.Atoi(idStr)
	if err != nil {
		http.Error(w, "无效的商品ID", http.StatusBadRequest)
		return
	}

	// 调用模型层的 DeleteProduct 函数来删除商品
	rowsAffected, err := models.DeleteProduct(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// 检查是否有商品被删除
	if rowsAffected == 0 {
		http.Error(w, "商品未找到", http.StatusNotFound)
		return
	}

	// 删除成功后，返回 200 OK 状态
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{
		"message": "商品删除成功",
	})
}

// GetProductsByType 获取指定类型的商品列表
    // @Summary 获取指定类型的商品
    // @Description 根据商品类型返回所有该类型的商品
    // @Tags 商品
    // @Accept json
    // @Produce json
    // @Param type query string true "商品类型"
    // @Success 200 {array} models.Product "商品列表"
    // @Failure 400 {string} string "无效的查询参数"
    // @Failure 500 {string} string "服务器内部错误"
    // @Router /products/type [get]
func GetProductsByType(w http.ResponseWriter, r *http.Request) {

    // 获取查询参数
    productType := r.URL.Query().Get("keyword")    // 通过 "type" 查询参数获取

    // 打印查询参数
    log.Println("Product Type:", productType)

    if productType == "" {
        w.Header().Set("Content-Type", "application/json")
        http.Error(w, `{"message": "商品类型不能为空"}`, http.StatusBadRequest)
        return
    }

    // 调用模型层函数获取商品列表
    products, err := models.GetProductsByType(productType)
    if err != nil {
        w.Header().Set("Content-Type", "application/json")
        http.Error(w, fmt.Sprintf(`{"message": "获取商品列表失败: %v"}`, err), http.StatusInternalServerError)
        return
    }

    // 如果没有找到商品，返回空数组而不是错误
    if len(products) == 0 {
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode([]models.Product{})
        return
    }

    // 返回商品列表
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(products)
}
